/**
 *                            License
 * THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS  
 * CREATIVE COMMONS PUBLIC LICENSE ("CCPL" OR "LICENSE"). 
 * THE WORK IS PROTECTED BY COPYRIGHT AND/OR OTHER APPLICABLE LAW.  
 * ANY USE OF THE WORK OTHER THAN AS AUTHORIZED UNDER THIS LICENSE OR  
 * COPYRIGHT LAW IS PROHIBITED.
 * 
 * BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND  
 * AGREE TO BE BOUND BY THE TERMS OF THIS LICENSE. TO THE EXTENT THIS LICENSE  
 * MAY BE CONSIDERED TO BE A CONTRACT,
 * THE LICENSOR GRANTS YOU THE RIGHTS CONTAINED 
 * HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS AND CONDITIONS.
 * 
 */
package lineage.model.gametime;

import java.sql.Time;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.TimeZone;

import lineage.util.RangeInt;

/**
 * 游戏时间.
 * 
 * @version 2014年3月16日下午1:53:56
 * @author jrwz
 */
public final class L1GameTime {
    /** 2003年7月3日 12:00(UTC) 1月1日00:00. */
    private static final long BASE_TIME_IN_MILLIS_REAL = 1057233600000L;
    /** 时间. */
    private final int time;
    /** 日历/日期. */
    private final Calendar calendar;

    /**
     * 游戏时间.
     * 
     * @param time
     *            - 时间
     */
    private L1GameTime(final int time) {
        this.time = time;
        calendar = makeCalendar(time);
    }

    /**
     * 标注日期.
     * 
     * @param time
     *            - 时间
     * @return 日期
     */
    private Calendar makeCalendar(final int time) {
        final Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
        cal.setTimeInMillis(0); // 用给定的 long 值设置此 Calendar 的当前时间值
        cal.add(Calendar.SECOND, time); // 指示一分钟中的秒
        return cal;
    }

    /**
     * 将参数中的值转换为L1GameTime类型.
     * 
     * @param timeMillis
     *            - 时间
     * @return 新的L1GameTime对象
     */
    public static L1GameTime valueOf(final long timeMillis) {
        final long t1 = timeMillis - BASE_TIME_IN_MILLIS_REAL;
        if (t1 < 0) {
            throw new IllegalArgumentException();
        }
        final int t2 = (int) ((t1 * 6) / 1000L);
        final int t3 = t2 % 3; // 调整时间为3的倍数
        return new L1GameTime(t2 - t3);
    }

    /**
     * 取得系统当前时间.
     * 
     * @return 当前时间
     */
    public static L1GameTime getSystemCurrentTime() {
        return L1GameTime.valueOf(System.currentTimeMillis());
    }

    /**
     * 将参数中的值转换为L1GameTime类型.
     * 
     * @param time
     *            - Time对象
     * @return 新的L1GameTime对象
     */
    public static L1GameTime valueOf(final Time time) {
        final long t = time.getTime() + TimeZone.getDefault().getRawOffset();
        return new L1GameTime((int) (t / 1000L));
    }

    /**
     * .
     * 
     * @return
     */
    public Time toTime() {
        final int t = time % (24 * 3600);
        return new Time(t * 1000L - TimeZone.getDefault().getRawOffset());
    }

    public int get(final int field) {
        return calendar.get(field);
    }

    /**
     * 取得(秒).
     * 
     * @return time
     */
    public int getSeconds() {
        return time;
    }

    /**
     * 取得日期.
     * 
     * @return 日期
     */
    public Calendar getCalendar() {
        return (Calendar) calendar.clone(); // 创建并返回此对象的一个副本
    }

    /**
     * 是否为晚上.
     * 
     * @return 如果是晚上则返回true
     */
    public boolean isNight() {
        final int hour = calendar.get(Calendar.HOUR_OF_DAY);
        return !RangeInt.includes(hour, 6, 17); // 6:00-17:59(白天)不在这个范围内则返回true
    }

    @Override
    public String toString() {
        final SimpleDateFormat f = new SimpleDateFormat("yyyy.MM.dd G 'at' HH:mm:ss z");
        f.setTimeZone(calendar.getTimeZone());
        return f.format(calendar.getTime()) + "(" + this.getSeconds() + ")";
    }
}
